#pragma once
#include <sys/epoll.h>
#include <string.h>

#include "log.hpp"
#include "common.hpp"
#include "connection.hpp"

/*基于epoll的监听分发模块*/
class epoller{
private:
void Create(int size){//防止用户重复创建epoll模型，将该接口封闭起来
    int n=::epoll_create(size);
    if(n==-1){
        LOG(ERROR)<<"epoll create error"<<strerror(errno);
        exit(EPOLL_CREATE_ERR);
    }
    _epfd=n;
    LOG(DEBUG)<<"epfd:"<<_epfd<<" create successful";
    
}

public:
    epoller(int size=256){//设什么值无所谓，但是一定要大于0
        Create(size);
    }
    ~epoller(){

    }

    int wait(struct epoll_event* revents,int rMaxSize,int timeout){
        int n=::epoll_wait(_epfd,revents,rMaxSize,timeout);//默认阻塞式等待
        return n;
    }

    int add(const connection& con){//向epoll模型中添加事件
        struct epoll_event ev;
        ev.events=con.GetEvent();
        ev.data.fd=con.GetFd();
        int n=epoll_ctl(_epfd,EPOLL_CTL_ADD,con.GetFd(),&ev);
        return n;
    }

    int modifer(const connection& con){//修改epoll模型中的事件
        struct epoll_event ev;
        ev.data.fd=con.GetFd();
        ev.events=con.GetEvent();
        int n=epoll_ctl(_epfd,EPOLL_CTL_MOD,con.GetFd(),&ev);
        return n;
    }


    int del(const connection& con){//删除epoll模型中的fd，注意要保证删除的fd是合法的
        int fd=con.GetFd();
        int n=epoll_ctl(_epfd,EPOLL_CTL_DEL,fd,nullptr);
        return n;
    }
private:
    int _epfd;
};